﻿using ConfigInfoWebPlatform.Model;
using ConfigInfoWebPlatform.Model.Dtos.SelectDtos;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace ConfigInfoWebPlatform.API.DBCommon
{
    /// <summary>
    /// 功能导航数据层
    /// </summary>
    public class DAL_ProgramNavicat
    {
        private IFreeSql freeSql;
        /// <summary>
        /// 功能导航数据层
        /// </summary>
        public DAL_ProgramNavicat()
        {
            freeSql = FreesqlFactory.GetFreeSql("configplatform");
        }
        /// <summary>
        /// 获取功能导航信息
        /// </summary>
        /// <returns></returns>
        public List<ProgramNavicatModel> GetProgramNavicatInfos()
        {
            var query = freeSql.Select<ProgramNavicat,MenuStatistics>()
                               .LeftJoin((a,b)=>a.Id==b.NavicatId)
                               .Where((a,b)=>a.Navicatflag==1)
                                .ToList((a,b) => new ProgramNavicatModel
                                {
                                    ID = a.Id,
                                    ParentId = a.ParentId,
                                    AllParentId = a.AllParentId,
                                    Code = a.Code,
                                    Name = a.Name,
                                    Level = a.Level,
                                    Directory = a.Directory,
                                    Index = a.Index,
                                    NavicatFlag = a.Navicatflag,
                                    Note = a.Note,
                                    Img = a.Img,
                                    Href = a.Href,
                                    IsDirectory=a.IsDirectory,
                                    IsStatistics=a.IsStatistics,
                                    FloderNum=b.FloderNumber.HasValue?b.FloderNumber:0,
                                    FileNum=b.FileNumber.HasValue?b.FileNumber:0
                                });
            return query;
        }
        /// <summary>
        /// 获取功能导航信息
        /// </summary>
        /// <returns></returns>
        public ProgramNavicatModel GetProgramNavicatInfoById(long id)
        {
            // 查询导航信息
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Navicatflag == 1)
                             .Where(x => x.Id == id)
                             .ToOne(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 AllParentId = x.AllParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });
            return query;
        }



        /// <summary>
        /// 根据目录获取导航功能ID
        /// </summary>
        /// <param name="directory">导航的对应的目录</param>
        /// <returns></returns>
        public long GetProgramId(string directory)
        {
            directory = directory.Replace("\\", @"/");
            // 查询功能导航ID
            string programId = string.Empty;
            string relativeDir = string.Empty;
            string[] splitArr = directory.Split(new string[] { @"/config/" }, StringSplitOptions.None);
            if (splitArr.Length >= 2)
                relativeDir = @"/config/" + splitArr[splitArr.Length - 1];
            else
                relativeDir = directory;
            relativeDir = relativeDir.Replace(@"\", "/");
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Directory == relativeDir)
                             .ToOne(x => x.Id);
            return query;



        }

        /// <summary>
        /// 根据角色Id查询菜单Id
        /// </summary>
        public List<long> GetProgramNavicatIds(string rid)
        {
            var query = freeSql.Select<Authority, ProgramNavicat>()
                             .InnerJoin((a, b) => a.PNId == b.Id.ToString())
                             .Where((a, b) => a.RId == rid)
                             .ToList((a, b) => b.Id);
            return query;
        }

        /// <summary>
        /// 根据code获取导航功能ID
        /// </summary>
        public long GetProgramIdByCode(string code)
        {
            var programId = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Code == code)
                             .ToOne(x => x.Id);
            return programId;
        }

        /// <summary>
        /// 根据code获取导航功能实体
        /// </summary>
        public ProgramNavicatModel GetProgramEntityByCode(string code)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Code == code)
                             .ToOne(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 AllParentId = x.AllParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });
            return query;
        }

        /// <summary>
        /// 获取指定功能ID下的子功能
        /// </summary>
        /// <param name="parentProgramId">父级ID</param>
        /// <returns></returns>
        public List<ProgramNavicatModel> GetChildProgram(long parentProgramId)
        {
            // 查询导航信息
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.ParentId == parentProgramId)
                             .ToList(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 AllParentId = x.AllParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });
            return query;
        }

        /// <summary>
        /// 更新菜单栏
        /// </summary>
        /// <param name="programNavicat"></param>
        /// <returns></returns>
        public int UpdateNavicat(ProgramNavicatModel programNavicat)
        {
            ProgramNavicat model = new ProgramNavicat();
            model.Id = programNavicat.ID;
            model.ParentId = programNavicat.ParentId.HasValue ? programNavicat.ParentId.Value : 0;
            model.Code = programNavicat.Code;
            model.Name = programNavicat.Name;
            model.Level = programNavicat.Level;
            model.Directory = programNavicat.Directory;
            model.Navicatflag = programNavicat.NavicatFlag;
            model.Img = programNavicat.Img;
            model.Href = programNavicat.Href;
            model.Index = programNavicat.Index;
            model.Note = programNavicat.Note;
            model.IsStatistics = programNavicat.IsStatistics;
            model.IsDirectory = programNavicat.IsDirectory;
            var result = freeSql.Update<ProgramNavicat>()
                              .SetSource(model)
                              .ExecuteAffrows();
            return result;
        }
        /// <summary>
        /// 插入菜单栏
        /// </summary>
        /// <param name="programNavicat"></param>
        /// <returns></returns>
        public int InsertNavicat(ProgramNavicatModel programNavicat)
        {
            ProgramNavicat model = new ProgramNavicat();
            model.Id = programNavicat.ID;
            model.ParentId = programNavicat.ParentId;
            model.Code = programNavicat.Code;
            model.Name = programNavicat.Name;
            model.Level = programNavicat.Level;
            model.Directory = programNavicat.Directory;
            model.Navicatflag = programNavicat.NavicatFlag;
            model.Img = programNavicat.Img;
            model.Href = programNavicat.Href;
            model.Index = programNavicat.Index;
            model.Note = programNavicat.Note;
            model.AllParentId = programNavicat.AllParentId;
            model.IsDirectory = programNavicat.IsDirectory;
            model.IsStatistics = programNavicat.IsStatistics;
            var result = freeSql.Insert<ProgramNavicat>(model)
                                .ExecuteAffrows();
            return result;
        }

        /// <summary>
        /// 获取流程导航树
        /// </summary>
        /// <returns></returns>
        public List<ProgramNavicatModel> GetProcessmNavicatInfos()
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Id >= 1001000000000000)
                             .Where(x => x.Id < 1002000000000000)
                             .Where(x => x.Navicatflag == 1)
                             .ToList(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 AllParentId = x.AllParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });

            return query;
        }

        /// <summary>
        /// 根据路径获取功能导航信息
        /// </summary>
        /// <returns></returns>
        public ProgramNavicatModel GetProgramNavicatInfoByDir(string directory)
        {
            // 查询导航信息
            directory = directory.Replace("/", @"\");
            // 查询功能导航ID
            string relativeDir = string.Empty;
            string[] splitArr = directory.Split(new string[] { "\\config\\" }, StringSplitOptions.None);
            if (splitArr.Length >= 2)
                relativeDir = "\\config\\" + splitArr[splitArr.Length - 1];
            else
                relativeDir = directory;
            relativeDir = relativeDir.Replace(@"\", "/");
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Directory == relativeDir)
                             .ToOne(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });
            return query;
        }

        /// <summary>
        /// 获取案件类型导航数据
        /// </summary>
        /// <returns></returns>
        public List<ProgramNavicatModel> GetCaseTypeNavicats()
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Id < 1002000000000000)
                             .Where(x => x.Level == 3)
                             .ToList(x => new ProgramNavicatModel
                             {
                                 ID = x.Id,
                                 ParentId = x.ParentId,
                                 Code = x.Code,
                                 Name = x.Name,
                                 Level = x.Level,
                                 Directory = x.Directory,
                                 Index = x.Index,
                                 NavicatFlag = x.Navicatflag,
                                 Note = x.Note,
                                 Img = x.Img,
                                 Href = x.Href
                             });
            return query;
        }

        /// <summary>
        /// 根据导航层级获取导航菜单下拉数据
        /// </summary>
        /// <param name="level">导航层级</param>
        /// <returns></returns>
        public List<ProgramNavicatSelectDto> GetParentsByLevel(int? level)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Level == level)
                             .Where(x => x.Navicatflag == 1)
                             .ToList(x => new ProgramNavicatSelectDto
                             {
                                 Id = x.Id,
                                 Name = x.Name,
                                 Index = x.Index
                             });
            return query;
        }

        public ProgramNavicat GetLastNav(long parentId)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.ParentId == parentId)
                             .OrderByDescending(x => x.Id)
                             .ToOne();

            return query;
        }

        public ProgramNavicat GetSingleNav(long id)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Id == id)
                             .OrderByDescending(x => x.Id)
                             .ToOne();
            return query;
        }

        public List<ProgramNavicat> GetAllNavicats()
        {
            var query = freeSql.Select<ProgramNavicat>().ToList();
            return query;
        }

        /// <summary>
        /// 通过等级获取菜单数据
        /// </summary>
        public List<ProgramNavicat> GetNavicatByLevel(int level)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Level == level)
                             .Where(x => x.Navicatflag == 1)
                             .ToList();
            return query;
        }

        /// <summary>
        /// 通过Id获取菜单数据
        /// </summary>
        public ProgramNavicat GetNavicatById(long id)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Id == id)
                             .Where(x => x.Navicatflag == 1)
                             .ToOne();
            return query;
        }

        /// <summary>
        /// 修改菜单AllParentId
        /// </summary>
        public bool UpdateNavicatAllParentId(long id, string allParentId)
        {
            var result = freeSql.Update<ProgramNavicat>()
                              .Set(x => x.AllParentId, allParentId)
                              .Where(x => x.Id == id)
                              .ExecuteAffrows();
            return result > 0;
        }

        /// <summary>
        /// 通过父级Id获取子级菜单
        /// </summary>
        public List<ProgramNavicat> GetChildNavicat(long parentId)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.ParentId == parentId)
                             .Where(x => x.Navicatflag == 1)
                             .ToList();
            return query;
        }

        /// <summary>
        /// 通过文件目录路径获取菜单信息
        /// </summary>
        public ProgramNavicat GetNavicatByDirPath(string dir)
        {
            var query = freeSql.Select<ProgramNavicat>()
                             .Where(x => x.Directory == dir)
                             .ToOne();
            return query;
        }

        public List<ProgramNavicat> GetNavicatByFilter(Expression<Func<ProgramNavicat, bool>> where)
        {
            var select = freeSql.Select<ProgramNavicat>()
                               .WhereIf(where != null, where)
                               .ToList();
            return select;
        }

        public List<MenusModel> GetProtramNavicatTree(string userName,string rid)
        {
            List<MenusModel> menus = new List<MenusModel>();
            List<ProgramNavicatModel> programNavicats = new List<ProgramNavicatModel>();
            if (userName == "admin")
            {
                programNavicats = GetProgramNavicatInfos();
            }
            else if (!string.IsNullOrWhiteSpace(rid))
            {
                var programNavicatIds = GetProgramNavicatIds(rid);
                if (programNavicatIds.Any())
                    programNavicats = GetProgramNavicatInfos()
                                    .Where(x => programNavicatIds.Contains(x.ID))
                                    .Where(x => x.Code != "navicatadmin")
                                    .ToList();
            }            
            foreach (var item in programNavicats?.Where(a => a.Level == 1).OrderBy(a => a.Index))
            {
                //找到第一层菜单
                string firstDesc = string.Empty;
                string firstTitle = string.Empty;
                if (item.IsStatistics == 1)
                {
                    firstDesc = $"{item.Name}({item.FloderNum}/{item.FileNum})";
                    firstTitle= $"{item.Name}(文件夹:{item.FloderNum} 文件:{item.FileNum})";
                }
                else
                {
                    firstDesc = item.Name;
                    firstTitle = item.Name;
                }
                    
                var menufirst = new MenusModel()
                {
                    Code = item.Code,
                    Directory = item.Directory?.Replace("\\", "/"),
                    Href = item.Href,
                    ID = item.ID,
                    Img = item.Img,
                    Index = item.Index,
                    Level = item.Level,
                    Name = item.Name,
                    NavicatFlag = item.NavicatFlag,
                    Note = item.Note,
                    NameDesc = firstDesc,
                    NameTitle=firstTitle,
                    IsStatistics = item.IsStatistics.Value
                };

                List<MenusModel> childs = new List<MenusModel>();
                foreach (var itemchild in programNavicats.Where(a => a.Level == 2 && a.ParentId == item.ID).OrderBy(a => a.Index))
                {
                    string twoDesc = string.Empty;
                    string twoTitle = string.Empty;
                    if (itemchild.IsStatistics == 1)
                    {
                        twoDesc= $"{itemchild.Name}({itemchild.FloderNum}/{itemchild.FileNum})";
                        twoTitle = $"{itemchild.Name}(文件夹:{itemchild.FloderNum} 文件:{itemchild.FileNum})";
                    }
                    else
                    {
                        twoDesc = itemchild.Name;
                        twoTitle = itemchild.Name;
                    }
                        
                    var menuchild = new MenusModel()
                    {
                        Code = itemchild.Code,
                        Directory = itemchild.Directory?.Replace("\\", "/"),
                        Href = itemchild.Href,
                        ID = itemchild.ID,
                        Img = itemchild.Img,
                        Index = itemchild.Index,
                        Level = itemchild.Level,
                        Name = itemchild.Name,
                        NavicatFlag = itemchild.NavicatFlag,
                        Note = itemchild.Note,
                        NameDesc = twoDesc,
                        NameTitle=twoTitle,
                        IsStatistics = item.IsStatistics.Value
                    };
                    List<MenusModel> threes = new List<MenusModel>();
                    foreach (var itemThree in programNavicats.Where(a => a.Level == 3 && a.ParentId == itemchild.ID).OrderBy(a => a.Index))
                    {
                        string threeDesc = string.Empty;
                        string threeTitle = string.Empty;
                        if (itemThree.IsStatistics == 1)
                        {
                            threeDesc= $"{itemThree.Name}({itemThree.FloderNum}/{itemThree.FileNum})";
                            threeTitle = $"{itemThree.Name}(文件夹:{itemThree.FloderNum} 文件:{itemThree.FileNum})";
                        }
                        else
                        {
                            threeDesc = itemThree.Name;
                            threeTitle = itemThree.Name;
                        }
                            
                        var menuThree = new MenusModel()
                        {
                            Code = itemThree.Code,
                            Directory = itemThree.Directory?.Replace("\\", "/"),
                            Href = itemThree.Href,
                            ID = itemThree.ID,
                            Img = itemThree.Img,
                            Index = itemThree.Index,
                            Level = itemThree.Level,
                            Name = itemThree.Name,
                            NavicatFlag = itemThree.NavicatFlag,
                            Note = itemThree.Note,
                            NameDesc = threeDesc,
                            NameTitle=threeTitle,
                            IsStatistics = item.IsStatistics.Value
                        };
                        threes.Add(menuThree);
                    }
                    if (threes != null && threes.Any())
                        menuchild.ChildMenus = threes.ToArray();
                    childs.Add(menuchild);
                }

                menufirst.ChildMenus = childs.ToArray();
                menus.Add(menufirst);
            }
            return menus;
        }
    }
}
